package com.testing.sunnycommon.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.testing.sunnycommon.annotations.SunnyAdvice;
import com.testing.sunnycommon.mapper.SunnyMailConfMapper;
import com.testing.sunnycommon.model.Result;
import com.testing.sunnycommon.model.SunnyProject;
import com.testing.sunnycommon.model.SunnyResult;
import com.testing.sunnycommon.model.SunnyResultDetail;
import com.testing.sunnycommon.model.mail.SunnyMailConf;
import com.testing.sunnycommon.service.SunnyMailService;
import com.testing.sunnycommon.service.SunnyProjectService;
import com.testing.sunnycommon.service.SunnyResultDetailService;
import com.testing.sunnycommon.service.SunnyResultService;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import javax.mail.Message;
import javax.mail.internet.MimeMessage;
import java.io.ByteArrayOutputStream;
import java.util.List;
import java.util.Properties;
import java.util.stream.Collectors;

/**
 * @Classname SunnyMailServiceImpl
 * @Description 类型说明
 * @Date 2023/6/16 21:21
 * @Created by 特斯汀Roy
 */
@Service
public class SunnyMailServiceImpl extends ServiceImpl<SunnyMailConfMapper, SunnyMailConf> implements SunnyMailService {

    @Autowired
    TemplateEngine templateEngine;

    @Autowired
    SunnyResultDetailService sunnyResultDetailService;

    @Autowired
    SunnyResultService sunnyResultService;

    @Autowired
    SunnyProjectService sunnyProjectService;

    @Override
    public Result sendTestMail(SunnyMailConf sunnyMailConf) {
        JavaMailSenderImpl javaMailSender = initMailSender(sunnyMailConf);
        //完成邮件的发送。
        //创建mimeMessage的对象来完成邮件内容编辑。
        try {
            MimeMessage mimeMessage = javaMailSender.createMimeMessage();
            mimeMessage.setSubject("sunny测试平台测试邮件");
            //设置收件人列表
            mimeMessage.setRecipients(Message.RecipientType.TO, sunnyMailConf.getReceiverList());
            //设置抄送人列表
            mimeMessage.setRecipients(Message.RecipientType.CC, sunnyMailConf.getCopyList());
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage);
            helper.setFrom(sunnyMailConf.getMailAccount());
            //创建一个Context类型的对象，用于处理模板文件
            Context context = new Context();
            //设置模板中的变量
            context.setVariable("nickname", sunnyMailConf.getSenderNickname());
            //将模板html文件，转为字符串完成发送。
            String mailContent = templateEngine.process("mail/TestMail.html", context);
            //如果发送的html格式的信息，记得加上第二个参数，是否为html，为true
            helper.setText(mailContent, true);
            //进行发送
            javaMailSender.send(mimeMessage);
            return Result.success("发送测试邮件成功", "发送测试邮件成功");
        } catch (Exception e) {
            log.error("发送测试邮件失败",e.fillInStackTrace());
            return Result.fail(1100, "发送测试邮件失败，请检查邮件配置", e.fillInStackTrace());
        }
    }

    @SunnyAdvice("发送邮件报告")
    @Override
    @Async
    public Result sendReportMail(SunnyMailConf sunnyMailConf, Long resultId) {
        //结果报告信息
        SunnyResult result = sunnyResultService.getById(resultId);
        //通过先相除得到小数，然后乘以10000得到一个4位数，最后除以100得到最终结果
        String passRate = (int) (((float) result.getPassCount() / result.getCaseCount()) * 10000) / 100.00f + "%";
        String status = result.getCaseCount() == result.getPassCount() ? "Pass" : "fail";

        //用例结果信息的整合
        List<SunnyResultDetail> resultDetailList = sunnyResultDetailService.list(new LambdaQueryWrapper<SunnyResultDetail>()
                .eq(SunnyResultDetail::getResultId, result.getId()));
        List<SunnyResultDetail> caseDetailList = resultDetailList.stream()
                .filter(sunnyResultDetail -> sunnyResultDetail.getParentId() == null)
                .collect(Collectors.toList());
        //获取项目名和执行次数
        SunnyProject project = sunnyProjectService.getById(result.getProjectId());
        String projectName = project.getName();
        String buildOrder = result.getBuildOrder().toString();

        System.out.println("所有用例级别的结果详情是" + caseDetailList);

        JavaMailSenderImpl javaMailSender = initMailSender(sunnyMailConf);
        //完成邮件的发送。
        //创建mimeMessage的对象来完成邮件内容编辑。
        try {
            MimeMessage mimeMessage = javaMailSender.createMimeMessage();
            mimeMessage.setSubject(!sunnyMailConf.getMailTitle().equals("") ? sunnyMailConf.getMailTitle() : "sunny测试平台【" + projectName + "】项目的第" + buildOrder + "次执行报告");
            //设置收件人列表
            mimeMessage.setRecipients(Message.RecipientType.TO, sunnyMailConf.getReceiverList());
            //设置抄送人列表
            mimeMessage.setRecipients(Message.RecipientType.CC, sunnyMailConf.getCopyList());
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
            helper.setFrom("1508353980@qq.com");
            //创建一个Context类型的对象，用于处理模板文件
            Context context = new Context();
            //设置模板中的变量
            context.setVariable("company", sunnyMailConf.getCompanyName());
            context.setVariable("projectName", projectName);
            context.setVariable("buildOrder", buildOrder);
            context.setVariable("result", result);
            context.setVariable("passRate", passRate);
            context.setVariable("status", status);
            context.setVariable("resultDetails", caseDetailList);
            context.setVariable("nickname", sunnyMailConf.getSenderNickname());
            //将模板html文件，转为字符串完成发送。
            String mailContent = templateEngine.process("mail/report.html", context);
            //如果发送的html格式的信息，记得加上第二个参数，是否为html，为true
            helper.setText(mailContent, true);
            XSSFWorkbook workbook = sunnyResultService.exportResult(resultId);
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            workbook.write(outputStream);
            //将输出流转为字节数组
            byte[] excelBytes = outputStream.toByteArray();
            //创建字节数组资源
            ByteArrayResource byteArrayResource = new ByteArrayResource(excelBytes);
            helper.addAttachment(projectName + "项目第" + buildOrder + "次执行报告.xlsx", byteArrayResource);
            //进行发送
            javaMailSender.send(mimeMessage);
            return Result.success("发送【" + projectName + "】项目第" + buildOrder + "执行报告邮件成功", null);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.fail(1100, "发送【" + projectName + "】项目第" + buildOrder + "执行报告邮件失败，请检查邮件配置", e.fillInStackTrace());
        }
    }

    private JavaMailSenderImpl initMailSender() {
        JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
        javaMailSender.setHost("smtp.qq.com");
        javaMailSender.setPort(465);
        javaMailSender.setUsername("1508353980@qq.com");
        javaMailSender.setPassword("ongoauxowrokieii");
        javaMailSender.setProtocol("smtp");
        javaMailSender.setDefaultEncoding("utf-8");
        //设置邮箱的SSl鉴权操作
        Properties mailProps = new Properties();
        mailProps.setProperty("mail.smtp.auth", "true");
        mailProps.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        //鉴权参数设置
        javaMailSender.setJavaMailProperties(mailProps);
        return javaMailSender;
    }


    private JavaMailSenderImpl initMailSender(SunnyMailConf sunnyMailConf) {
        JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
        javaMailSender.setHost(sunnyMailConf.getSmtpServer());
        javaMailSender.setPort(sunnyMailConf.getSmtpPort());
        javaMailSender.setUsername(sunnyMailConf.getMailAccount());
        javaMailSender.setPassword(sunnyMailConf.getMailPassword());
        javaMailSender.setProtocol("smtp");
        javaMailSender.setDefaultEncoding("utf-8");
        //设置邮箱的SSl鉴权操作
        Properties mailProps = new Properties();
        mailProps.setProperty("mail.smtp.auth", "true");
        mailProps.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        //鉴权参数设置
        javaMailSender.setJavaMailProperties(mailProps);
        return javaMailSender;
    }
}
